import { Request, Response } from 'express';
import bcrypt from 'bcryptjs';
import jwt from 'jsonwebtoken';
import { prisma } from '@/config/database';
import { config } from '@/config';
import { logger } from '@/utils/logger';
import ApiError from '@/utils/ApiError';
import catchAsync from '@/utils/catchAsync';

export class AuthController {
  // 用户注册
  register = catchAsync(async (req: Request, res: Response) => {
    const { username, password, nickname } = req.body;

    // 检查用户名是否已存在
    const existingUser = await prisma.user.findUnique({
      where: { username }
    });

    if (existingUser) {
      throw new ApiError(400, '用户名已存在');
    }

    // 加密密码
    const hashedPassword = await bcrypt.hash(password, 12);

    // 创建用户
    const user = await prisma.user.create({
      data: {
        username,
        password: hashedPassword,
        nickname: nickname || username,
      },
      select: {
        id: true,
        username: true,
        nickname: true,
        avatar: true,
        createdAt: true,
      }
    });

    // 生成令牌
    const accessToken = this.generateAccessToken(user.id);
    const refreshToken = this.generateRefreshToken(user.id);

    logger.info(`用户注册成功: ${user.username}`);

    res.status(201).json({
      success: true,
      message: '注册成功',
      data: {
        user,
        accessToken,
        refreshToken
      }
    });
  });

  // 用户登录
  login = catchAsync(async (req: Request, res: Response) => {
    const { username, password } = req.body;

    // 查找用户
    const user = await prisma.user.findUnique({
      where: { username },
      select: {
        id: true,
        username: true,
        password: true,
        nickname: true,
        avatar: true,
      }
    });

    if (!user) {
      throw new ApiError(401, '用户名或密码错误');
    }

    // 验证密码
    const isPasswordValid = await bcrypt.compare(password, user.password);
    if (!isPasswordValid) {
      throw new ApiError(401, '用户名或密码错误');
    }

    // 生成令牌
    const accessToken = this.generateAccessToken(user.id);
    const refreshToken = this.generateRefreshToken(user.id);

    // 更新在线状态
    await prisma.user.update({
      where: { id: user.id },
      data: { 
        isOnline: true,
        lastSeen: new Date()
      }
    });

    logger.info(`用户登录成功: ${user.username}`);

    res.json({
      success: true,
      message: '登录成功',
      data: {
        user: {
          id: user.id,
          username: user.username,
          nickname: user.nickname,
          avatar: user.avatar,
        },
        accessToken,
        refreshToken
      }
    });
  });

  // 刷新令牌
  refreshToken = catchAsync(async (req: Request, res: Response) => {
    const { refreshToken } = req.body;

    if (!refreshToken) {
      throw new ApiError(401, '刷新令牌不能为空');
    }

    try {
      const decoded = jwt.verify(refreshToken, config.jwt.secret) as { userId: string };
      
      // 验证用户是否存在
      const user = await prisma.user.findUnique({
        where: { id: decoded.userId },
        select: {
          id: true,
          username: true,
          nickname: true,
          avatar: true,
        }
      });

      if (!user) {
        throw new ApiError(401, '用户不存在');
      }

      // 生成新的令牌
      const newAccessToken = this.generateAccessToken(user.id);
      const newRefreshToken = this.generateRefreshToken(user.id);

      res.json({
        success: true,
        data: {
          accessToken: newAccessToken,
          refreshToken: newRefreshToken
        }
      });
    } catch (error) {
      throw new ApiError(401, '无效的刷新令牌');
    }
  });

  // 用户登出
  logout = catchAsync(async (req: Request, res: Response) => {
    const userId = (req as any).user.id;

    // 更新在线状态
    await prisma.user.update({
      where: { id: userId },
      data: { 
        isOnline: false,
        lastSeen: new Date()
      }
    });

    res.json({
      success: true,
      message: '登出成功'
    });
  });

  // 获取当前用户信息
  getCurrentUser = catchAsync(async (req: Request, res: Response) => {
    const userId = (req as any).user.id;

    const user = await prisma.user.findUnique({
      where: { id: userId },
      select: {
        id: true,
        username: true,
        nickname: true,
        avatar: true,
        isOnline: true,
        lastSeen: true,
        createdAt: true,
        updatedAt: true,
      }
    });

    if (!user) {
      throw new ApiError(404, '用户不存在');
    }

    res.json({
      success: true,
      data: { user }
    });
  });

  // 生成访问令牌
  private generateAccessToken(userId: string): string {
    return jwt.sign(
      { userId },
      config.jwt.secret,
      { expiresIn: config.jwt.accessExpiresIn } as jwt.SignOptions
    );
  }

  // 生成刷新令牌
  private generateRefreshToken(userId: string): string {
    return jwt.sign(
      { userId },
      config.jwt.secret,
      { expiresIn: config.jwt.refreshExpiresIn } as jwt.SignOptions
    );
  }
}